<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    // js基础面试  深浅拷贝  数组去重  原型  继承  闭包
    const obj = { 
      uname: 'zs',
      age: 12,
      info: {
        address: '航头',
        tel: 110
      },
      arr: [1, 2, 3, 4]
     }
    //  let o = obj // 地址交换, 只要字段的值修改 都会影响
    //  console.log(o);
    //  console.log(obj);

    //  --------------------
    //--浅拷贝 循环遍历对象的方式 这种方式实现的也是浅拷贝, 基本数据类型修改不会影响, 复杂数据类型一修改还是会影响
   /* let o = {}
    for (let k in obj){
        o[k] = obj[k]
    }
    o.info.tel = 120
    console.log(o);
    console.log(obj); */

    //--------es6 新增的对象合并的方法, 和{}合并就是一个浅拷贝
  /* let o = {}
   const res = Object.assign(obj, o) // 做对象合并
   res.info.tel = 120
   console.log(res);
   console.log(obj); */

   //--------------------------------浅拷贝以上都是 ------------------------------

  // 深拷贝
  // 1. JSON.parse + JSON.stringify 
  /*const o = JSON.parse(JSON.stringify(obj))
    o.info.tel = 120
    console.log(o);
    console.log(obj); */

   // 2. 递归 
  function deepClone(oldObj, newObj) {
      for(let k in oldObj) {
        const item = oldObj[k] // item是每一个字段对应的值
        // if(item instanceof Array) {
        if(item.constructor === Array) {
          newObj[k] = [] // 将新对象的键对应的值设置为一个数组
          deepClone(item, newObj[k])
        }else if(item.constructor === Object) {
          newObj[k] = {} // 将新对象的键对应的值设置为一个对象
          deepClone(item, newObj[k])
        }else {
          newObj[k] = item
        }
      }
      return newObj
    }
  const res =  deepClone(obj, {})
  res.info.tel = 120
  console.log(res);
  console.log(obj);
  // lodash cloneDeep()
  // 检测数据类型
  // typeof 只能检测基本数据类型 
  // instanceof 检测复杂数据类型 返回值是一个布尔值  {} instanceof Object
  // constructor
  //  构造函数创建了实例  构造函数的原型 .prototype  实例对象__proto__ 指向构造函数的原型
  // 构造函数的原型.constructor指回了构造函数
  console.log(Object.prototype.constructor === Object);
  console.log({}.constructor === Object);


  </script>
</body>
</html>